/// \file      VigilatorLocal.h
/// \brief     Clase VigilatorLocal que contiene la logica para la vigilancia de sectores de seguridad
/// \version   1.0
/// \author    grupo vigilancia
/// \date      12 de Enero de 2012

#ifndef VIGILATORLOCAL_H
#define VIGILATORLOCAL_H

#include <common/Common.h>       // Libreria Shared
#include <vigilance_comm.h>      // Topicos de vigilancia, el include.pri esta en el archivo .pro
#include <simulation_comm.h>
#include <navigationaid_comm.h>
#include <KinematicsLib.h>       // Libreria kinematics, permite usar su espacio de nombres y su funcionalidad
#include "DemoTypes.h"

#include "vigilance/util/DetectionAlgorithm.h"
#include "vigilance/util/Timer.h"
#include <map>
#include <list>

using namespace varayoc::simulation;
using namespace varayoc::navigationaid;
using namespace varayoc::kinematics::util;

namespace varayoc
{
namespace vigilance
{
namespace runnable
{

class VigilatorLocal
{
private:
   ///   \brief   Constructor
   ///
   ///            Constructor de la clase VigilatorLocal.
   VigilatorLocal();
   ///
   ///   \brief   Lectura de los contactos del topic
   ///
   ///            Realiza la lectura de la coleccion de los Track Simulados
   ///            realiza el filtrado de los track mas cercanos
   ///            detecta la incursion de contactos dentro del sector de vigilancia
   Void  readCollectionTrack();
   ///
   ///   \brief   Inicializacion de las tablas de vigilancia
   ///            Tablas de tracks simulados totales y tracks cercanos por Sector de Seguridad. SS
   ///            Tablas de almacenamiento de topicos Figura: Circulares fijos y relativos, Poligonos fijos y relativos
   ///
   Void  initialize();
   ///
   ///   \brief   Lectura de los topicos de vigilancia
   ///            Realiza la topicos TrackVigilanceAlarm y VigilanceAlarm
   ///            utilizado para test
   Void  readSecuritySectorCollection();
   ///
   ///   \brief   Lectura de los tracks simulados y reales
   ///            Realiza la lectura de tracks simulados filtrados por clasificacion y en la región descrita por el query
   ///            Escribe en la tabla correspondiente
   Void  readFilteredTrackCollection();
   ///
   ///   \brief   Lectura de los figuras designadas como sectores de seguridad
   ///            Realiza la lectura de las figuras: Circular y Poligonal
   ///            se escriben en la tabla correspondiente
   Void  readFilteredFigureCollection();
   ///
   ///   \brief   Elimina el topico TrackVigilanceAlarm especificado por el OID pasado como parametro
   ///
   Void  deleteTrackVigilanceAlarm(OID TrackVigilanceAlarmId);
   ///
   ///   \brief   Elimina el topico VigilanceAlarm especificado por el OID pasado como parametro
   ///
   Void  deleteVigilanceAlarm(OID VigilanceAlarmId);
   ///
   ///   \brief   Realiza un barrido de la lista que contiene los topicos figura en estado dispose
   ///            Se borran en orden los topicos TrackVigilanceAlarm y VigilanceAlarm, relacionados a cada topico figura
   ///
   Void  deletingTopicsRelatedFigureTopics();
   ///
   ///   \brief   Realiza un barrido de la lista que contiene los topicos track en estado dispose
   ///            Se borran en orden los topicos TrackVigilanceAlarm y VigilanceAlarm, relacionados a cada topico track
   ///
   Void  deletingTopicsRelatedTrackTopics();
   ///
   ///   \brief   realiza el proceso de deteccion de invasion de sector de seguridad SS
   ///            por topico figura y por topico track, realiza la evaluacion de la invasion
   ///            si una invasion es detectada, se escribe tanto el topico VigilanciaAlarm como el topico TrackVigilanceAlarm
   ///            si un track detectado sale del SS, se escribe los cambios de estado a dispose de los respectivos topicos de Vigilancia
   ///
   Void  detectionProcess();
   ///
   ///   \brief   Copias de las tablas actuales a tablas recientes de las tablas de deteccion y topicos de Vigilancia
   ///            Creacion de las listas recientes de Tracks y Figuras
   ///
   Void  makeEarlierDataVigilance();
   ///
   ///   \brief   verifica la existencia del par <OID Track, Tipo de Track> en la lista mas reciente de tracks detectados "m_earlierListOfTracksFound"
   ///   \return  Verdadero si el OID es encontrado en la lista
   ///
   Bool  isThereTrackOId(pair<string, UInt> TrackOId);
   ///
   ///   \brief   Crea un lista de tracks detectados dentro del SS representado por el OID de la Figura
   ///   \return  Devuelve en una lista los OID's de los tracks detectados para el SS
   ///
   list<string>   getTrackListOfFigureTopicOfTable(pair<string, UInt> FigureTopic, multimap<pair<string, UInt>, pair<string, UInt> > Tabla);
   ///
   ///   \brief   Encuentra los tracks simulados cercanos al SS Circular actual
   ///            Necesita estar definido el SS circular actual
   ///            Escribe en la tabla m_nearSimTrackHash, los tracks simulados detectados si los hubiere
   ///
   Void  findSimTracksCloseToCircularFigure();
   ///
   ///   \brief   Encuentra los tracks cercanos al SS Poligonal actual
   ///            Necesita estar definido el SS poligonal actual
   ///            Escribe en la tabla relacionada, los tracks detectados si los hubiere
   ///
   Void  findSimTracksCloseToPolylineFigure();
   ///
   ///   \brief   Detecta si el track simulado actual esta dentro del SS - Figura actual
   ///            Emite los topicos relacionados al par actual (Figura, Track) o
   ///            Elimina los topicos relacionados al par actual (Figura, Track)
   ///            Para los SS posibles, circulares y poligonales
   ///
   Void  findInvasionsToSecuritySectorToSimulatedTrack(navigationaid::FigureType  figureType);
   ///
   ///   \brief   Tiempo actual del Sistema, usado como parametro en la escritura del topic VigilanceAlarm
   ///
   Timestamp   getCurrentTime();
   ///
   ///   \brief   Obtencion del rango minimo y maximo para la latitud y longitud universo
   ///            utilizado despues de la lectura de las figuras etiquetadas como SS
   ///   \return  Vector con los valores limite
   ///

   ///   \brief   verifica el estado actual para el Topic desde la lista posible en el case
   ///
   ///   \return  Verdadero si el estado del topic es disposed, uno de los estados de la lista
   ///
   Bool  isDisposedState(ddswrapper::DataInfo di);
   ///
   Bool  isTimeIntervalValid(SimulatedTrack_ptr entity);
   ///
   Bool  writeSimulatedTrackKinematic(SimulatedTrack_ptr entity);
   ///
   Void  processingTrack(ddswrapper::DataInfo di, SimulatedTrack_ptr nearbyTrack);

   SecuritySectorFigureTopic  scFigureTopic;       // tipo de topico figura actual, fijo o relativo?

   OID         m_nodeId;
   OID         m_trackId;
   UInt        m_timeUpdate;
   Timestamp   timeStart;
   Int32       timeNowInSeconds;
   Float64     m_distance;
   Float       fr;                                 // factor de redimensionamiento del rectangulo relativo al sector de seguridad
   OID         m_nodeConfigurate;                  ///< Nodo identificador de la consola
   Bool        m_running;                          ///< flag para continuar con el evento ciclico

   Vector<Float64>::Type                           m_LimLatitude;       ///< Limites de Latitud para la busqueda de tracks
   Vector<Float64>::Type                           m_LimLongitude;      ///< Limites de Longitud para la busqueda de tracks

   GeoCoordinate_ptr                               m_kinematics;        ///< Puntero inteligente para utilizar la libreria de calculo

   // smart pointers globales para las figuras
   RelativeCircularFigureKinematic_ptr             m_currentRelativeCircularSector;
   FixedCircularFigure_ptr                         m_currentFixedCircularSector;
   RelativePolylineFigureKinematic_ptr             m_currentRelativePolylineSector;
   FixedPolylineFigure_ptr                         m_currentFixedPolylineSector;

   // smart pointers globales para los tracks
   SimulatedTrackKinematic_ptr                     m_currentSimulatedTrackKinematic;

   // DDS
   VigilanceAlarmWriter_ptr                        m_vawriter;       ///< Puntero inteligente para la publicacion del topic de alarmas
   TrackVigilanceAlarmWriter_ptr                   m_tvawriter;
   // Readers para test
   VigilanceAlarmReader_ptr                        m_vareader;
   TrackVigilanceAlarmReader_ptr                   m_tvareader;
   // Lectura de Tracks simulados
   SimulatedTrackReader_ptr                        m_streader;       ///< Puntero inteligente para la lectura de los contactos del topic
   // Lectura de Topicos Figuras (Circular & Polyline)
   RelativeCircularFigureKinematicReader_ptr       m_rcfkreader;
   FixedCircularFigureReader_ptr                   m_fcfreader;
   RelativePolylineFigureKinematicReader_ptr       m_rpfkreader;
   FixedPolylineFigureReader_ptr                   m_fpfreader;
   // para simular la lectura
   FixedCircularFigureWriter_ptr                   m_fcfwriter;
   FixedPolylineFigureWriter_ptr                   m_fpfwriter;

   SimulatedTrackKinematicWriter_ptr               m_stk_writer;     ///< Puntero intelogente para la publicacion del topic de posiciones
   SimulatedTrackKinematicReader_ptr               m_stk_reader;     ///< Puntero intelogente para la publicacion del topic de posiciones

   // Tablas
   HashMap<OID, Int32>::Type                                m_frequency;            ///<Matriz para almacenar los ids de los contactos y el tiempo transcurrido

   HashMap<OID, SimulatedTrackKinematic_ptr>::Type          m_allSimTrackHash;      // matriz que almacena el total de los tracks simulados
   HashMap<OID, SimulatedTrackKinematic_ptr>::Type          m_nearSimTrackHash;     // matriz que almacena los tracks simulados cercanos al SS actual

   // tabla que almacena solo SS de tipo circularFigure y que no tienen el estado dispose
   HashMap<OID, RelativeCircularFigureKinematic_ptr>::Type  m_relativeCircularHash;
   HashMap<OID, FixedCircularFigure_ptr>::Type              m_fixedCircularHash;
   // tabla que almacena solo SS de tipo polylineFigure y que no tienen el estado dispose
   HashMap<OID, RelativePolylineFigureKinematic_ptr>::Type  m_relativePolylineHash;
   HashMap<OID, FixedPolylineFigure_ptr>::Type              m_fixedPolylineHash;

   // par: Id Figure, Id Track, usado en la lectura inicial de los topicos Figure y SimulatedTrack
   multimap<pair<string, UInt>, pair<string, UInt> >  m_currentVigilanceMap;        // <(OID, FigureTopicType), (OID, TrackTopicType)>
   multimap<pair<string, UInt>, pair<string, UInt> >  m_earlierVigilanceMap;        // copia de m_currentVigilanceMap

   // par: Id Figure, Id VigilanceAlarm, usado en la generación de topicos VigilanceAlarm
   map<string, string>                                m_earlierOIdsVigAlarm;        // <OID_Fig, OID_VigAlarm> mas reciente
   map<string, string>                                m_currentOIdsVigAlarm;        // <OID_Fig, OID_VigAlarm> actual

   // par: <Id Figure, Id Track>, Id TrackVigilanceAlarm, usado en la generación de topicos TrackVigilanceAlarm
   map<pair<string, string>, string>                  m_earlierOIdsTrackVigAlarm;
   map<pair<string, string>, string>                  m_currentOIdsTrackVigAlarm;

   // Listas
   list<pair<string, UInt> >                          m_DisposeFigureTopics;        // Aqui se alamacenan los OID's de los SS que se reconocen en estado dispose en la lectura de los Topicos Figura
   list<pair<string, UInt> >                          m_DisposeTrackTopics;         // Aqui se alamacenan los OID's de los Tracks que se reconocen en estado dispose en la lectura de los Topicos Track
   list<pair<string, UInt> >                          m_earlierListOfFiguresFound;  // Lista de Figuras desde m_earlierVigilanceMap
   list<pair<string, UInt> >                          m_earlierListOfTracksFound;   // Lista de Tracks desde m_earlierVigilanceMap

   // Clase que implementa los algoritmos de Deteccion
   vigilance::util::DetectionAlgorithm                detectionAlgorithm;

   // Timers por cada clasificacion de Track
   varayoc::vigilance::util::Timer_ptr m_verify_class_aereo;
   varayoc::vigilance::util::Timer_ptr m_verify_class_super;
   Bool  m_ClassSuper;
   Bool  m_ClassAereo;

public:
   ///   \brief   Crea un puntero inteligente de tipo VigilatorLocal.
   ///            Metodo estatico que crea una instancia a la clase VigilatorLocal.
   ///   \return  Retorna un puntero inteligente de tipo VigilatorLocal.
   static   VigilatorLocal_ptr   create();
   ///
   ///   \brief   Destructor
   ///            Libera el bloque de memoria reservado.
   virtual  ~VigilatorLocal();
   ///
   ///   \brief   Asigna el nodo Id de la consola
   ///            Inicializa el valor del Nodo Id de la consola
   Void     setNodoId(OID nodoId);
   ///
   ///   \brief   Inicia el modo Vigilancia
   ///
   Void     runVigilance();
   ///
   ///   \brief   Inicia el modo Vigilancia para prueba
   ///
   Void     runTester();
};

}
}
}

#endif // VIGILATORLOCAL_H
